package cn.com.generaldata.os.service.indicator_evaluation.industry_layout_analysis;

import java.math.BigDecimal;

import org.apache.commons.lang3.Validate;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Criteria;
import org.nutz.lang.random.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.generaldata.jsme_indicator_system.entity.IndicatorEvaluation;
import cn.com.generaldata.os.pojo.IndicatorAssociateResult;
import cn.com.generaldata.os.service.indicator_constant.ProvinceIndicatorConstant;
import cn.com.generaldata.os.service.indicator_evaluation.CalculateService;
import cn.com.generaldata.os.service.indicator_evaluation.CalculateServiceHelper;
import cn.com.generaldata.os.util.BeanMapper;
import cn.com.generaldata.os.vo.IndicatorAccountVO;

/**
 * 地理联系系数运算类.
 */
public class GeographicalRelationCalculateService implements CalculateService {

	private String BaseIndicatorName = ProvinceIndicatorConstant.MAJOR_MARINE_ADDVALUE_NAME;

	// 渔业增加值
	private String FishAddName = ProvinceIndicatorConstant.FISHERY_ADDVALUE_NAME;
	// 盐业增加值
	private String SaltAddName = ProvinceIndicatorConstant.SALT_ADDVALUE_NAME;
	// 船舶工业增加值
	private String MSIAddName = ProvinceIndicatorConstant.MSI_ADDVALUE_NAME;
	// 化工业增加值
	private String MCIAddName = ProvinceIndicatorConstant.MCI_ADDVALUE_NAME;
	// 生物医药业增加值
	private String MBIAddName = ProvinceIndicatorConstant.MBI_ADDVALUE_NAME;
	// 工程建筑业增加值
	private String MEAIAddName = ProvinceIndicatorConstant.MEAI_ADDVALUE_NAME;
	// 电力业增加值
	private String MEPIAddName = ProvinceIndicatorConstant.MEPI_ADDVALUE_NAME;
	// 海水利用业增加值
	private String MSUIAddName = ProvinceIndicatorConstant.MSUI_ADDVALUE_NAME;
	// 交通运输业增加值
	private String MCTIAddName = ProvinceIndicatorConstant.MCTI_ADDVALUE_NAME;
	// 滨海旅游业增加值
	private String CoastalTourAddName = ProvinceIndicatorConstant.COASTAL_TOUR_ADDVALUE_NAME;

	private String[] industrys = new String[] { FishAddName, SaltAddName,
			MSIAddName, MCIAddName, MBIAddName, MEAIAddName, MEPIAddName,
			MSUIAddName, MCTIAddName, CoastalTourAddName };

	private String[] areas = new String[] { "320600000000000",
			"320700000000000", "320900000000000" };

	private String[] industryCode = new String[] { "01", "04", "05", "06",
			"07", "08", "09", "10", "11", "12" };

	private final Logger logger = LoggerFactory.getLogger(getClass());

	private Dao dao;

	private Dao indicatorSystemDao;

	private CalculateServiceHelper helper;

	// 计算指标方法
	@Override
	public void calculateIndicator(IndicatorEvaluation indicator,
			IndicatorAccountVO indicatorAccountVO) {

		// 三地各产业占比重
		Double[][] industryAddValues = new Double[industrys.length][areas.length];

		// 计算比重值
		for (int i = 0; i < industrys.length; i++) {
			// 沿海三市
			for (int j = 0; j < areas.length; j++) {

				IndicatorAccountVO countryIndicator = BeanMapper.map(indicatorAccountVO, IndicatorAccountVO.class);
				countryIndicator.setAreaId(areas[j]);
				Double currentBase = getBaseIndicatorVal(countryIndicator, countryIndicator.getYear(),
						BaseIndicatorName, 5);
				Double currentParent = getBaseIndicatorVal(countryIndicator, countryIndicator.getYear(), industrys[i],
						7);
				if (currentBase.equals(Double.valueOf(0))) {
					// industryAddValues[i][j] = Double.valueOf(0);
					continue;
				}
				industryAddValues[i][j] = (currentParent / currentBase) * 100;

			}
		}
		// 存各产业地理联系系数
		for (int i = 0; i < industrys.length; i++) {
			getAssociateValue(i, areas.length, industryAddValues, indicatorAccountVO, indicator);
		}

	}

	private void saveIndicatorEvaluationResult(IndicatorAssociateResult ier) {
		// 保存新记录
		Chain chain = Chain.make("id", R.UU16());
		chain.add("indicator_id", ier.getIndicatorId());
		chain.add("area_id", ier.getAreaId());
		chain.add("self_code", ier.getSelfCode());
		chain.add("ass_code", ier.getAssCode());
		chain.add("year", ier.getYear());

		chain.add("indicator_value", ier.getIndicatorValue());

		dao.insert("tbl_indicator_associate_result", chain);
	}

	private Criteria getIndicatorAccountingDataCri(
			IndicatorAssociateResult indicatorAccountVO) {
		Criteria cri = Cnd.cri();
		cri.where().and("indicator_id", "=",
				indicatorAccountVO.getIndicatorId());
		cri.where().and("self_code", "=", indicatorAccountVO.getSelfCode());
		cri.where().and("ass_code", "=", indicatorAccountVO.getAssCode());
		cri.where().and("area_id", "=", indicatorAccountVO.getAreaId());
		cri.where().and("year", "=", indicatorAccountVO.getYear());
		return cri;
	}

	@Override
	public void setDao(Dao dao) {
		this.dao = dao;
	}

	@Override
	public void setIndicatorSystemDao(Dao indicatorSystemDao) {
		this.indicatorSystemDao = indicatorSystemDao;
	}

	// 计算某产业与其他各产业地理联系系数
	private void getAssociateValue(int industryNum, int total,
			Double[][] industryAddValues,
			IndicatorAccountVO indicatorAccountVO, IndicatorEvaluation indicator) {
		for (int i = 0; i < industrys.length; i++) {
			Double sum = new Double(0);
			if (i == industryNum)
			// 这里是存一个自己对自己关联度为1还是直接跳过？
			{
				IndicatorAssociateResult ier = new IndicatorAssociateResult();
				ier.setAssCode(industryCode[i]);
				ier.setIndicatorId(indicator.getId());
				ier.setSelfCode(industryCode[industryNum]);
				ier.setIndicatorValue((Double.valueOf(100)));
				ier.setYear(indicatorAccountVO.getYear());
				ier.setAreaId("320000000000000");
				Criteria cri = getIndicatorAccountingDataCri(ier);
				Record record = dao.fetch("tbl_indicator_associate_result", cri);
				if (record != null) {
					dao.clear("tbl_indicator_associate_result", cri);
				}
				saveIndicatorEvaluationResult(ier);
				continue;
			}
			// 三个地区的某两产业地理相关度
			for (int j = 0; j < total; j++) {
				sum += Math
						.abs(industryAddValues[industryNum][j]
								- industryAddValues[i][j]);
			}
			Double ga = 100 - sum / 2;
			BigDecimal bg = new BigDecimal(ga);
			ga = bg.setScale(10, BigDecimal.ROUND_HALF_UP).doubleValue();
			IndicatorAssociateResult ier = new IndicatorAssociateResult();
			ier.setAssCode(industryCode[i]);
			ier.setIndicatorId(indicator.getId());
			ier.setSelfCode(industryCode[industryNum]);
			ier.setIndicatorValue(ga);
			ier.setYear(indicatorAccountVO.getYear());
			ier.setAreaId("320000000000000");
			Criteria cri = getIndicatorAccountingDataCri(ier);

			Record record = dao
					.fetch("tbl_indicator_associate_result", cri);
			if (record != null) {
				dao.clear("tbl_indicator_associate_result", cri);
			}

			saveIndicatorEvaluationResult(ier);
		}
	}

	private Double getBaseIndicatorVal(IndicatorAccountVO indicatorAccountVO,
			int year, String name, Integer category) {
		// Integer BaseIndicatorId = getIndicatorId(name, category);
		// if (BaseIndicatorId == null) {
		// return Double.valueOf(0);
		// }
		// Criteria cri = getIndicatorDataCri(indicatorAccountVO, year,
		// BaseIndicatorId);
		// Record record = dao.fetch("tbl_indicator_data", cri);
		//
		// Double result = null;
		// if (record == null) {
		// result = Double.valueOf(0);
		// } else {
		// result = Castors.me().castTo(record.get("indicator_value"),
		// Double.class);
		// }
		Double inputOrAccountingIndicatorValue = helper.getInputOrAccountingIndicatorValue(indicatorAccountVO, year,
				name);
		Validate.isTrue(inputOrAccountingIndicatorValue != null);
		return inputOrAccountingIndicatorValue;
	}

	@Override
	public void setCalculateServiceHelper(CalculateServiceHelper calculateServiceHelper) {
		helper = calculateServiceHelper;
	}

}
